import Taro from '@tarojs/taro'
import { User, ChefStatus, Order, OrderStatus } from '../types'
import { CloudDataManager } from './cloud'
import { errorUtils, ErrorType } from './errorHandler'

// 厨师工作负载计算结果
interface ChefWorkload {
  chefId: string;
  chefName: string;
  activeOrders: number;
  estimatedCompletionTime: number;
  lastOrderTime?: Date;
  status: ChefStatus;
}

// 订单分配结果
interface OrderAssignmentResult {
  success: boolean;
  chefId?: string;
  chefName?: string;
  error?: string;
  estimatedTime?: number;
}

export class ChefUtils {
  // 厨师每单平均处理时间（分钟）
  private static readonly AVG_ORDER_TIME = 15;
  // 厨师最大并发订单数
  private static readonly MAX_CONCURRENT_ORDERS = 5;
  // 厨师自动离线时间（毫秒）
  private static readonly AUTO_OFFLINE_TIME = 3 * 60 * 60 * 1000; // 3小时

  /**
   * 更新厨师状态
   * @param userId 厨师ID
   * @param status 新状态
   * @returns Promise<boolean>
   */
  static async updateChefStatus(userId: string, status: ChefStatus): Promise<boolean> {
    try {
      // 验证用户是否为厨师
      const user = await CloudDataManager.getUserById(userId)
      if (!user || user.role !== 'chef') {
        throw new Error('用户不是厨师')
      }
      
      // 更新状态
      await CloudDataManager.updateData('users', userId, {
        status,
        lastActiveAt: new Date(),
        updatedAt: new Date()
      })
      
      console.log(`厨师 ${userId} 状态已更新为 ${status}`)
      return true
    } catch (error) {
      errorUtils.handleError(error, ErrorType.DATABASE, {
        showToast: true,
        data: { userId, operation: 'updateChefStatus' }
      })
      return false
    }
  }

  /**
   * 获取所有厨师
   * @param status 可选的状态筛选
   * @returns Promise<User[]>
   */
  static async getAllChefs(status?: ChefStatus): Promise<User[]> {
    try {
      // 构建查询条件
      const query: any = { role: 'chef' }
      if (status) {
        query.status = status
      }
      
      const chefs = await CloudDataManager.getAllData('users', query)
      
      // 过滤掉长时间未活跃的厨师
      return chefs.filter(chef => {
        // 如果厨师已标记为离线，直接返回
        if (chef.status === 'offline') return true
        
        // 检查最后活跃时间
        if (chef.lastActiveAt) {
          const lastActive = new Date(chef.lastActiveAt).getTime()
          const now = Date.now()
          
          // 如果超过自动离线时间，自动将状态视为离线
          if (now - lastActive > this.AUTO_OFFLINE_TIME) {
            // 不在这里更新数据库，只是在返回结果中标记
            chef.status = 'offline'
          }
        }
        
        return true
      })
    } catch (error) {
      console.error('获取厨师列表失败:', error)
      return []
    }
  }

  /**
   * 获取可用厨师数量
   * @returns Promise<number>
   */
  static async getAvailableChefsCount(): Promise<number> {
    try {
      const chefs = await this.getAllChefs('available')
      return chefs.length
    } catch (error) {
      console.error('获取可用厨师数量失败:', error)
      return 0
    }
  }

  /**
   * 智能分配订单给最合适的厨师
   * @param orderId 订单ID
   * @param priority 优先级（1-10，数字越大优先级越高）
   * @returns Promise<OrderAssignmentResult>
   */
  static async assignOrderToChef(
    orderId: string,
    priority: number = 5
  ): Promise<OrderAssignmentResult> {
    try {
      // 1. 获取订单信息
      const order = await CloudDataManager.getData('orders', orderId) as Order
      if (!order) {
        return {
          success: false,
          error: '订单不存在'
        }
      }
      
      if (order.status !== 'pending') {
        return {
          success: false,
          error: '只能分配待处理的订单'
        }
      }
      
      // 2. 获取所有可用的厨师
      const availableChefs = await this.getAllChefs('available')
      
      if (availableChefs.length === 0) {
        return {
          success: false,
          error: '没有可用的厨师'
        }
      }
      
      // 3. 计算每个厨师的当前工作负载
      const workloads: ChefWorkload[] = await Promise.all(
        availableChefs.map(async chef => {
          const workload = await this.calculateChefWorkload(chef.id)
          return {
            chefId: chef.id,
            chefName: chef.name,
            ...workload,
            status: chef.status as ChefStatus
          }
        })
      )
      
      // 4. 根据工作负载和其他因素选择最合适的厨师
      const selectedChef = this.selectBestChef(workloads, order)
      
      if (!selectedChef) {
        return {
          success: false,
          error: '无法找到合适的厨师'
        }
      }
      
      // 5. 更新订单信息，分配给选中的厨师
      const estimatedTime = this.calculateEstimatedTime(selectedChef.activeOrders + 1)
      const updatedOrder = {
        ...order,
        assignedChefId: selectedChef.chefId,
        assignedChefName: selectedChef.chefName,
        status: 'confirmed' as OrderStatus,
        estimatedTime,
        priority,
        updatedAt: new Date()
      }
      
      await CloudDataManager.saveOrder(updatedOrder)
      
      // 6. 如果厨师工作负载达到阈值，更新厨师状态
      if (selectedChef.activeOrders + 1 >= this.MAX_CONCURRENT_ORDERS) {
        await this.updateChefStatus(selectedChef.chefId, 'busy')
      }
      
      return {
        success: true,
        chefId: selectedChef.chefId,
        chefName: selectedChef.chefName,
        estimatedTime
      }
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : '订单分配失败'
      }
    }
  }

  /**
   * 计算厨师工作负载
   * @param chefId 厨师ID
   * @returns Promise<{activeOrders: number, estimatedCompletionTime: number, lastOrderTime?: Date}>
   */
  static async calculateChefWorkload(chefId: string): Promise<{
    activeOrders: number;
    estimatedCompletionTime: number;
    lastOrderTime?: Date;
  }> {
    try {
      // 获取该厨师当前处理中的订单
      const orders = await CloudDataManager.getAllData('orders', {
        assignedChefId: chefId,
        status: 'confirmed' // 只计算已确认但未完成的订单
      }) as Order[]
      
      // 计算活跃订单数
      const activeOrders = orders.length
      
      // 计算预计完成时间（分钟）
      const estimatedCompletionTime = activeOrders * this.AVG_ORDER_TIME
      
      // 获取最近一单的时间
      let lastOrderTime: Date | undefined
      if (orders.length > 0) {
        // 按更新时间排序
        orders.sort((a, b) => 
          new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
        )
        lastOrderTime = new Date(orders[0].updatedAt)
      }
      
      return {
        activeOrders,
        estimatedCompletionTime,
        lastOrderTime
      }
    } catch (error) {
      console.error(`计算厨师 ${chefId} 工作负载失败:`, error)
      return {
        activeOrders: 0,
        estimatedCompletionTime: 0
      }
    }
  }

  /**
   * 选择最合适的厨师
   * @param workloads 厨师工作负载列表
   * @param order 订单信息
   * @returns 选中的厨师或undefined
   */
  private static selectBestChef(workloads: ChefWorkload[], order: Order): ChefWorkload | undefined {
    if (workloads.length === 0) return undefined
    
    // 过滤掉工作量已满的厨师
    const availableChefs = workloads.filter(chef => 
      chef.activeOrders < this.MAX_CONCURRENT_ORDERS && chef.status === 'available'
    )
    
    if (availableChefs.length === 0) return undefined
    
    // 按工作量排序（从低到高）
    availableChefs.sort((a, b) => {
      // 首先按活跃订单数排序
      if (a.activeOrders !== b.activeOrders) {
        return a.activeOrders - b.activeOrders
      }
      
      // 如果活跃订单数相同，按最后接单时间排序（较早接单的优先）
      if (a.lastOrderTime && b.lastOrderTime) {
        return a.lastOrderTime.getTime() - b.lastOrderTime.getTime()
      }
      
      // 如果没有最后接单时间，有时间的排后面
      if (a.lastOrderTime) return 1
      if (b.lastOrderTime) return -1
      
      return 0
    })
    
    // 返回工作量最少的厨师
    return availableChefs[0]
  }

  /**
   * 计算预计完成时间（分钟）
   * @param activeOrders 活跃订单数
   * @returns 预计时间（分钟）
   */
  private static calculateEstimatedTime(activeOrders: number): number {
    return Math.max(this.AVG_ORDER_TIME, activeOrders * this.AVG_ORDER_TIME)
  }

  /**
   * 检查并更新厨师状态
   * @param chefId 厨师ID
   * @returns Promise<ChefStatus> 更新后的状态
   */
  static async checkAndUpdateChefStatus(chefId: string): Promise<ChefStatus> {
    try {
      // 获取厨师当前工作负载
      const workload = await this.calculateChefWorkload(chefId)
      
      // 获取厨师当前信息
      const chef = await CloudDataManager.getUserById(chefId)
      if (!chef || chef.role !== 'chef') {
        throw new Error('用户不是厨师')
      }
      
      // 当前状态
      const currentStatus = chef.status as ChefStatus || 'offline'
      
      // 根据工作负载确定应该的状态
      let newStatus: ChefStatus
      
      if (workload.activeOrders >= this.MAX_CONCURRENT_ORDERS) {
        newStatus = 'busy'
      } else if (workload.activeOrders > 0) {
        newStatus = 'available' // 有订单但未达到上限，可用
      } else {
        // 保持当前状态，除非是忙碌状态
        newStatus = currentStatus === 'busy' ? 'available' : currentStatus
      }
      
      // 如果状态需要更新
      if (newStatus !== currentStatus) {
        await this.updateChefStatus(chefId, newStatus)
      }
      
      return newStatus
    } catch (error) {
      console.error(`检查厨师 ${chefId} 状态失败:`, error)
      return 'offline' // 出错时默认为离线
    }
  }

  /**
   * 批量检查所有厨师状态
   * @returns Promise<void>
   */
  static async checkAllChefsStatus(): Promise<void> {
    try {
      // 获取所有厨师
      const chefs = await this.getAllChefs()
      
      // 逐个检查并更新状态
      for (const chef of chefs) {
        if (chef.id) {
          await this.checkAndUpdateChefStatus(chef.id)
        }
      }
      
      console.log('所有厨师状态检查完成')
    } catch (error) {
      console.error('检查所有厨师状态失败:', error)
    }
  }

  /**
   * 重新分配订单
   * @param orderId 订单ID
   * @param excludeChefId 排除的厨师ID
   * @returns Promise<OrderAssignmentResult>
   */
  static async reassignOrder(
    orderId: string, 
    excludeChefId?: string
  ): Promise<OrderAssignmentResult> {
    try {
      // 1. 获取订单信息
      const order = await CloudDataManager.getData('orders', orderId) as Order
      if (!order) {
        return {
          success: false,
          error: '订单不存在'
        }
      }
      
      // 2. 获取所有可用的厨师
      let availableChefs = await this.getAllChefs('available')
      
      // 排除指定厨师
      if (excludeChefId) {
        availableChefs = availableChefs.filter(chef => chef.id !== excludeChefId)
      }
      
      if (availableChefs.length === 0) {
        return {
          success: false,
          error: '没有可用的厨师'
        }
      }
      
      // 3. 计算每个厨师的当前工作负载
      const workloads: ChefWorkload[] = await Promise.all(
        availableChefs.map(async chef => {
          const workload = await this.calculateChefWorkload(chef.id)
          return {
            chefId: chef.id,
            chefName: chef.name,
            ...workload,
            status: chef.status as ChefStatus
          }
        })
      )
      
      // 4. 选择最合适的厨师
      const selectedChef = this.selectBestChef(workloads, order)
      
      if (!selectedChef) {
        return {
          success: false,
          error: '无法找到合适的厨师'
        }
      }
      
      // 5. 更新订单信息
      const estimatedTime = this.calculateEstimatedTime(selectedChef.activeOrders + 1)
      const updatedOrder = {
        ...order,
        assignedChefId: selectedChef.chefId,
        assignedChefName: selectedChef.chefName,
        estimatedTime,
        updatedAt: new Date()
      }
      
      await CloudDataManager.saveOrder(updatedOrder)
      
      // 6. 如果厨师工作负载达到阈值，更新厨师状态
      if (selectedChef.activeOrders + 1 >= this.MAX_CONCURRENT_ORDERS) {
        await this.updateChefStatus(selectedChef.chefId, 'busy')
      }
      
      return {
        success: true,
        chefId: selectedChef.chefId,
        chefName: selectedChef.chefName,
        estimatedTime
      }
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : '订单重新分配失败'
      }
    }
  }

  /**
   * 格式化厨师状态
   * @param status 状态
   * @returns 格式化后的状态文本
   */
  static formatChefStatus(status?: ChefStatus): string {
    const statusMap: Record<ChefStatus, string> = {
      available: '空闲',
      busy: '忙碌',
      offline: '离线'
    }
    
    return statusMap[status || 'offline']
  }

  /**
   * 获取厨师状态颜色
   * @param status 状态
   * @returns 状态颜色
   */
  static getChefStatusColor(status?: ChefStatus): string {
    const colorMap: Record<ChefStatus, string> = {
      available: '#34c759', // 绿色
      busy: '#ff9500',      // 橙色
      offline: '#8e8e93'    // 灰色
    }
    
    return colorMap[status || 'offline']
  }
}

// 导出工具函数
export const chefUtils = {
  updateChefStatus: ChefUtils.updateChefStatus,
  getAllChefs: ChefUtils.getAllChefs,
  getAvailableChefsCount: ChefUtils.getAvailableChefsCount,
  assignOrderToChef: ChefUtils.assignOrderToChef,
  calculateChefWorkload: ChefUtils.calculateChefWorkload,
  checkAndUpdateChefStatus: ChefUtils.checkAndUpdateChefStatus,
  checkAllChefsStatus: ChefUtils.checkAllChefsStatus,
  reassignOrder: ChefUtils.reassignOrder,
  formatChefStatus: ChefUtils.formatChefStatus,
  getChefStatusColor: ChefUtils.getChefStatusColor
} 